/* DISCLAIMER
Original file written by Johnny on Flame.
This piece is protected by the GPLv3 License. Commercial uses of this should only happen with my consent.
JohnnyonFlame (a_t) Hotmail (d_o_t) com
*/

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "menu.h"
#include "items.h"
#include <stdio.h>

#include "settings.h"

SDL_Surface* background = NULL;
SDL_Surface* batt_sprite = NULL;
SDL_Surface* overlay = NULL;
SDL_Surface* screen = NULL;
unsigned int isRunning = 1;
TTF_Font *font = NULL;
TTF_Font *font_sel = NULL;
TTF_Font *font_status = NULL;
int m_index = 0;
unsigned int changed = 0;
int scroll_y = 1;
int ticks=0;
int fps=0;
int nextrender=0;
int nextupdate=0;
char batt[8];
int blevel = 2;

List_Items *display_menu;

void *garbage_collector[MAX_GARBAGE];
int garbage_ammount = -1;

void MENU_Init(){
	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

	SDL_Surface* ld_IMG = NULL;
	ld_IMG = IMG_Load( DEFAULT_BACKGROUND );

	if (!ld_IMG) {
		printf("ERROR: %s\n", SDL_GetError());
		return;
	}

	background = SDL_DisplayFormat(ld_IMG);
	SDL_FreeSurface(ld_IMG);

	ld_IMG = NULL;
	ld_IMG = IMG_Load( BATT_SPRITE );

	if (!ld_IMG) {
		printf("ERROR: %s\n", SDL_GetError());
		return;
	}

	batt_sprite = SDL_DisplayFormatAlpha(ld_IMG);
	SDL_FreeSurface(ld_IMG);

	if( TTF_Init() == -1 ) { isRunning = 0; }

	font = TTF_OpenFont(TTF_FONT, TTF_SIZE);
	font_sel = TTF_OpenFont(TTF_SELECTED_FONT, TTF_SELECTED_SIZE);
	font_status = TTF_OpenFont(TTF_STATUS_FONT, TTF_STATUS_SIZE);
	if (!(font || font_sel || font_status)){
		printf("ERROR: %s\n", SDL_GetError());
		return;
	}
	
	MENU_Start();
}

void MENU_Unload(){
	SDL_FreeSurface( background ); 
	SDL_FreeSurface( screen ); 
}

void doCallback(){
	if (display_menu->items[m_index].funcCallback != NULL ){
		display_menu->items[m_index].funcCallback();
	}
}

void Draw_MENU(){
	int i=-1;
	//if (i<-1) i = -1;

	if (scroll_y<0) scroll_y/=2;
	if (scroll_y>0) scroll_y/=2;

	if (changed)
	{
		if (display_menu->items[m_index].overlay_file!=NULL){
			if (overlay!=NULL)
			{
				SDL_FreeSurface(overlay);
			}
			SDL_Surface *ld_IMG = IMG_Load( display_menu->items[m_index].overlay_file );
			if (ld_IMG) {
				overlay = SDL_DisplayFormatAlpha(ld_IMG);
				SDL_FreeSurface(ld_IMG);
			}	
			else {
				printf("Could not load overlay %s.\n",display_menu->items[m_index].overlay_file);
				overlay=NULL;
			}
		}
		else
		{
			if (overlay)
			{
				SDL_FreeSurface(overlay);
				overlay = NULL;
			}
		}
		changed = 0;
	}
	
	SDL_BlitSurface( background, NULL, screen, NULL );

	SDL_Rect rec;

	if (overlay) {	

		rec.x = ( SCREEN_WIDTH - overlay->w ) / 2;
		rec.y = ( SCREEN_HEIGHT - overlay->h ) / 2 - scroll_y;	

		SDL_BlitSurface( overlay, NULL, screen, &rec );

	}

	char buffer[32];

	sprintf(buffer, "HH:MM DD/MM/YY");

	SDL_Surface *msg = TTF_RenderText_Solid(font_status, buffer, TTF_STATUS_COLOR);

	/*rec.x = ( SCREEN_WIDTH - msg->w ) / 2;
	rec.y = 0;
	rec.w = 0;
	rec.h = 0;*/
	SDL_BlitSurface( msg, NULL, screen, NULL );

	SDL_FreeSurface(msg);	

	if (nextupdate<=SDL_GetTicks()){

		FILE * pFile;

		pFile = fopen ("/sys/class/power_supply/battery/capacity" , "r");
		if (pFile == NULL) sprintf(batt, "%s", "NaN"); else
		{
			if ( fgets (batt , 8 , pFile) != NULL )
			puts (batt);
			fclose (pFile);
			blevel = BATT_SPRITE_COUNT - (atoi(&batt) / BATT_SPRITE_COUNT);
		}

		nextupdate = SDL_GetTicks() + UPDATE_BATTERY;
	}

	sprintf(buffer, "%s%%", batt);

	msg = TTF_RenderText_Solid(font_status, buffer, TTF_STATUS_COLOR);

	rec.x = ( SCREEN_WIDTH - msg->w )-BATT_SPRITE_WIDTH;
	rec.y = 0;
	rec.w = 0;
	rec.h = 0;

	SDL_BlitSurface( msg, NULL, screen, &rec );

	SDL_FreeSurface(msg);

	SDL_Rect recx;

	rec.x = ( SCREEN_WIDTH - BATT_SPRITE_WIDTH );
	rec.y = 0;
	rec.w = 0;
	rec.h = 0;

	recx.x = BATT_SPRITE_WIDTH*blevel;
	recx.y = 0;
	recx.w = BATT_SPRITE_WIDTH;
	recx.h = BATT_SPRITE_HEIGHT;

	SDL_BlitSurface( batt_sprite, &recx, screen, &rec );

	//Re-Implement draw menu.
	drawMenu(m_index, 0, 0, display_menu);

	SDL_Flip( screen );
}

void setDisplayMenu(List_Items* list){
	if (list==NULL) return;
	display_menu = list;
	scroll_y=m_index*TTF_SIZE;
	m_index=0;	
}

void drawMenu(int index, int x, int y, List_Items *menu){
	int i=-1;	
	SDL_Rect rec;


	while (i<(int)menu->count-1){
		i++;	
		
		TTF_Font *fnt = font;
		int size=TTF_SIZE;
	
		if (i==index) {
			//size = TTF_SELECTED_SIZE;	
			fnt = font_sel;
		}

		if ((i<index-2) || (i>index+2)) continue;
		
		//rec.y = (FONT_SIZE+1)*(i+1);

		SDL_Surface *msg = menu->items[i].drawCallback(fnt ,menu->items[i].label, (i==index), i);
		rec.x = (( SCREEN_WIDTH - msg->w ) / 2)+x;
		rec.y = (( SCREEN_HEIGHT - msg->h ) / 2 + ((TTF_SIZE*3/2)*(i-index)) + scroll_y)+y;
		SDL_BlitSurface( msg, NULL, screen, &rec );
		SDL_FreeSurface( msg );
	}
}

void MENU_Start(){
	while (isRunning){

		if (SDL_GetTicks()>=nextrender){
			fps = (SDL_GetTicks()-fps); if (fps!=0) fps = 1000/(fps); else fps = 0;//Bad coding practice, I know, stfu.
			int delay = SDL_GetTicks();
			Draw_MENU();
			delay = SDL_GetTicks() - delay;
			if (scroll_y!=0) //ONLY RE-RENDER IF NEEDED.
			{
				nextrender = SDL_GetTicks()+(TICKS_UPDATE-delay);
			}
			else
			{
				nextrender = SDL_GetTicks()+(TICKS_STILL-delay);
			}
			fps = SDL_GetTicks();
		}

		while ( SDL_PollEvent( &event ) ) {
			if( event.type == SDL_QUIT ) { 
				isRunning = 0;	
			}

			if( event.type == SDL_KEYDOWN )
			{
				switch( event.key.keysym.sym ) {
				case mKEY_UP: m_index--; scroll_y -= TTF_SIZE;changed = 1; nextrender=SDL_GetTicks(); break;
				case mKEY_DOWN: m_index++; scroll_y += TTF_SIZE; changed = 1; nextrender=SDL_GetTicks(); break;
				case mKEY_OK: doCallback(event); changed = 1; nextrender=SDL_GetTicks(); break;
				case mKEY_NO: setDisplayMenu(display_menu->previous); changed = 1; nextrender=SDL_GetTicks(); break;
				case mKEY_LEFT: doCallback(event); changed = 1; nextrender=SDL_GetTicks(); break;
				case mKEY_RIGHT: doCallback(event); changed = 1; nextrender=SDL_GetTicks(); break;
				default: break;
				}
				if (m_index<0) m_index=(int)display_menu->count-1;
				if (m_index>(int)display_menu->count-1) m_index=0;
			}
		} 
		SDL_Delay(16);
	}
}
